from typing import List, Dict, Any
from fastapi import APIRouter, Depends, HTTPException, status, Request
from sqlalchemy.orm import Session

from app.core.database.connection import get_database
from app.domains.user.services import UserService
from app.domains.user.schemas import (
    UserLogin, UserLoginResponse, UserRefreshToken, UserCreate, UserUpdate,
    UserResponse, UserListQuery, UserChangePassword, UserUpdateRole, UserProfile
)
from app.shared.schemas.response import success_response, paginated_response, error_response
from app.shared.exceptions.base import ValidationException, AuthenticationException, BusinessException
from app.shared.constants.status_codes import BusinessCode
from app.core.security.auth import auth_manager
from app.api.dependencies import get_current_user, require_roles
from app.shared.constants.enums import UserRole
import logging

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/auth", tags=["认证"])


@router.post("/login", response_model=dict, summary="用户登录")
async def login(
    user_credentials: UserLogin,
    request: Request,
    db: Session = Depends(get_database)
):
    """
    用户登录
    
    - **username**: 用户名
    - **password**: 密码
    - **remember_me**: 记住我（暂未实现）
    """
    try:
        user_service = UserService(db)
        
        # 认证用户
        user = user_service.authenticate(
            user_credentials.username,
            user_credentials.password
        )
        
        if not user:
            raise AuthenticationException("用户名或密码错误")
        
        # 获取客户端信息
        client_ip = request.client.host
        user_agent = request.headers.get("user-agent", "")
        
        # 创建会话
        session_data = user_service.create_user_session(
            user=user,
            device_info={"user_agent": user_agent},
            ip_address=client_ip,
            user_agent=user_agent
        )
        
        # 构造响应
        login_response = UserLoginResponse(
            access_token=session_data["access_token"],
            refresh_token=session_data["refresh_token"],
            token_type=session_data["token_type"],
            expires_in=session_data["expires_in"],
            user=UserResponse.from_orm(user)
        )
        
        logger.info(f"✅ 用户登录成功: {user.username} (IP: {client_ip})")
        
        return success_response(
            data=login_response.dict(),
            message="登录成功"
        )
        
    except AuthenticationException as e:
        logger.warning(f"⚠️  登录失败: {e}")
        return error_response(
            message=str(e),
            code=BusinessCode.LOGIN_FAILED
        )
    except BusinessException as e:
        logger.warning(f"⚠️  登录失败: {e}")
        return error_response(
            message=str(e),
            code=e.code
        )
    except Exception as e:
        logger.error(f"❌ 登录异常: {e}")
        return error_response(
            message="登录服务异常，请稍后重试",
            code=BusinessCode.OPERATION_FAILED
        )


@router.post("/refresh", response_model=dict, summary="刷新令牌")
async def refresh_token(
    token_data: UserRefreshToken,
    db: Session = Depends(get_database)
):
    """
    刷新访问令牌
    
    - **refresh_token**: 刷新令牌
    """
    try:
        user_service = UserService(db)
        
        session_data = user_service.refresh_user_session(
            token_data.refresh_token
        )
        
        return success_response(
            data=session_data,
            message="令牌刷新成功"
        )
        
    except AuthenticationException as e:
        logger.warning(f"⚠️  令牌刷新失败: {e}")
        return error_response(
            message=str(e),
            code=BusinessCode.TOKEN_INVALID
        )
    except Exception as e:
        logger.error(f"❌ 令牌刷新异常: {e}")
        return error_response(
            message="令牌刷新失败，请重新登录",
            code=BusinessCode.TOKEN_EXPIRED
        )


@router.post("/logout", response_model=dict, summary="用户登出")
async def logout(
    request: Request,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    用户登出
    """
    try:
        user_service = UserService(db)
        
        # 获取访问令牌
        authorization = request.headers.get("authorization", "")
        access_token = authorization.replace("Bearer ", "") if authorization.startswith("Bearer ") else None
        
        user_service.logout_user(
            user_id=current_user["user_id"],
            access_token=access_token
        )
        
        logger.info(f"✅ 用户登出成功: {current_user['username']}")
        
        return success_response(message="登出成功")
        
    except Exception as e:
        logger.error(f"❌ 登出异常: {e}")
        return error_response(
            message="登出失败",
            code=BusinessCode.OPERATION_FAILED
        )


# 用户管理路由
user_router = APIRouter(prefix="/users", tags=["用户管理"])


@user_router.post("", response_model=dict, summary="创建用户")
async def create_user(
    user_data: UserCreate,
    current_user: dict = Depends(require_roles([UserRole.ADMIN])),
    db: Session = Depends(get_database)
):
    """
    创建用户（仅管理员可操作）
    
    - **username**: 用户名（3-50个字符）
    - **password**: 密码（6-20个字符，必须包含字母和数字）
    - **email**: 邮箱（可选）
    - **phone**: 手机号（可选，中国手机号格式）
    - **full_name**: 全名（可选）
    - **role**: 用户角色
    - **is_active**: 是否激活
    """
    try:
        user_service = UserService(db)
        user = user_service.create_user(user_data)
        
        logger.info(f"✅ 用户创建成功: {user.username} by {current_user['username']}")
        
        return success_response(
            data=UserResponse.from_orm(user).dict(),
            message="用户创建成功"
        )
        
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except Exception as e:
        logger.error(f"❌ 创建用户异常: {e}")
        return error_response(
            message="创建用户失败",
            code=BusinessCode.OPERATION_FAILED
        )


@user_router.get("", response_model=dict, summary="获取用户列表")
async def get_user_list(
    query: UserListQuery = Depends(),
    current_user: dict = Depends(require_roles([UserRole.ADMIN, UserRole.MANAGER])),
    db: Session = Depends(get_database)
):
    """
    获取用户列表（管理员和经理可查看）
    
    - **page**: 页码（默认1）
    - **page_size**: 每页数量（默认20，最大100）
    - **search**: 搜索关键词（用户名、姓名、邮箱、手机号）
    - **role**: 角色筛选
    - **is_active**: 激活状态筛选
    - **sort_by**: 排序字段（默认created_at）
    - **sort_order**: 排序方向（asc/desc，默认desc）
    """
    try:
        user_service = UserService(db)
        users, total = user_service.get_user_list(query)
        
        # 转换为响应格式
        user_list = [UserResponse.from_orm(user).dict() for user in users]
        
        return paginated_response(
            items=user_list,
            total=total,
            page=query.page,
            page_size=query.page_size,
            message="查询成功"
        )
        
    except Exception as e:
        logger.error(f"❌ 获取用户列表异常: {e}")
        return error_response(
            message="获取用户列表失败",
            code=BusinessCode.OPERATION_FAILED
        )


@user_router.get("/me", response_model=dict, summary="获取当前用户信息")
async def get_current_user_info(
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    获取当前登录用户的详细信息
    """
    try:
        user_service = UserService(db)
        profile_data = user_service.get_user_profile(current_user["user_id"])
        
        user_profile = UserProfile.from_orm(profile_data["user"])
        
        # 添加统计信息
        user_profile.work_order_stats = profile_data["statistics"].get("work_orders")
        
        return success_response(
            data=user_profile.dict(),
            message="查询成功"
        )
        
    except Exception as e:
        logger.error(f"❌ 获取用户信息异常: {e}")
        return error_response(
            message="获取用户信息失败",
            code=BusinessCode.OPERATION_FAILED
        )


@user_router.get("/{user_id}", response_model=dict, summary="获取指定用户信息")
async def get_user_info(
    user_id: int,
    current_user: dict = Depends(require_roles([UserRole.ADMIN, UserRole.MANAGER])),
    db: Session = Depends(get_database)
):
    """
    获取指定用户的详细信息（管理员和经理可查看）
    """
    try:
        user_service = UserService(db)
        profile_data = user_service.get_user_profile(user_id)
        
        user_profile = UserProfile.from_orm(profile_data["user"])
        user_profile.work_order_stats = profile_data["statistics"].get("work_orders")
        
        return success_response(
            data=user_profile.dict(),
            message="查询成功"
        )
        
    except Exception as e:
        logger.error(f"❌ 获取用户信息异常: {e}")
        return error_response(
            message="获取用户信息失败",
            code=BusinessCode.DATA_NOT_FOUND if "不存在" in str(e) else BusinessCode.OPERATION_FAILED
        )


@user_router.put("/me", response_model=dict, summary="更新当前用户信息")
async def update_current_user(
    user_data: UserUpdate,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    更新当前登录用户的信息
    
    - **full_name**: 全名
    - **email**: 邮箱
    - **phone**: 手机号
    - **avatar_url**: 头像URL
    """
    try:
        user_service = UserService(db)
        user = user_service.update_user(current_user["user_id"], user_data)
        
        logger.info(f"✅ 用户信息更新成功: {user.username}")
        
        return success_response(
            data=UserResponse.from_orm(user).dict(),
            message="用户信息更新成功"
        )
        
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except Exception as e:
        logger.error(f"❌ 更新用户信息异常: {e}")
        return error_response(
            message="更新用户信息失败",
            code=BusinessCode.OPERATION_FAILED
        )


@user_router.put("/{user_id}", response_model=dict, summary="更新指定用户信息")
async def update_user_info(
    user_id: int,
    user_data: UserUpdate,
    current_user: dict = Depends(require_roles([UserRole.ADMIN])),
    db: Session = Depends(get_database)
):
    """
    更新指定用户的信息（仅管理员可操作）
    """
    try:
        user_service = UserService(db)
        user = user_service.update_user(user_id, user_data)
        
        logger.info(f"✅ 用户信息更新成功: {user.username} by {current_user['username']}")
        
        return success_response(
            data=UserResponse.from_orm(user).dict(),
            message="用户信息更新成功"
        )
        
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except Exception as e:
        logger.error(f"❌ 更新用户信息异常: {e}")
        return error_response(
            message="更新用户信息失败",
            code=BusinessCode.DATA_NOT_FOUND if "不存在" in str(e) else BusinessCode.OPERATION_FAILED
        )


@user_router.post("/change-password", response_model=dict, summary="修改密码")
async def change_password(
    password_data: UserChangePassword,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    修改当前用户密码
    
    - **old_password**: 旧密码
    - **new_password**: 新密码（6-20个字符，必须包含字母和数字）
    """
    try:
        user_service = UserService(db)
        
        user_service.change_password(
            user_id=current_user["user_id"],
            old_password=password_data.old_password,
            new_password=password_data.new_password
        )
        
        logger.info(f"✅ 密码修改成功: {current_user['username']}")
        
        return success_response(message="密码修改成功，请重新登录")
        
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except Exception as e:
        logger.error(f"❌ 修改密码异常: {e}")
        return error_response(
            message="修改密码失败",
            code=BusinessCode.OPERATION_FAILED
        )


@user_router.put("/{user_id}/role", response_model=dict, summary="更新用户角色")
async def update_user_role(
    user_id: int,
    role_data: UserUpdateRole,
    current_user: dict = Depends(require_roles([UserRole.ADMIN])),
    db: Session = Depends(get_database)
):
    """
    更新用户角色（仅管理员可操作）
    
    - **role**: 用户角色
    """
    try:
        user_service = UserService(db)
        
        # 不能修改自己的角色
        if user_id == current_user["user_id"]:
            return error_response(
                message="不能修改自己的角色",
                code=BusinessCode.OPERATION_FAILED
            )
        
        user_update = UserUpdate(role=role_data.role)
        user = user_service.update_user(user_id, user_update)
        
        logger.info(f"✅ 用户角色更新成功: {user.username} -> {role_data.role} by {current_user['username']}")
        
        return success_response(
            data=UserResponse.from_orm(user).dict(),
            message="用户角色更新成功"
        )
        
    except Exception as e:
        logger.error(f"❌ 更新用户角色异常: {e}")
        return error_response(
            message="更新用户角色失败",
            code=BusinessCode.DATA_NOT_FOUND if "不存在" in str(e) else BusinessCode.OPERATION_FAILED
        )


@user_router.delete("/{user_id}", response_model=dict, summary="删除用户")
async def delete_user(
    user_id: int,
    current_user: dict = Depends(require_roles([UserRole.ADMIN])),
    db: Session = Depends(get_database)
):
    """
    删除用户（仅管理员可操作）
    """
    try:
        user_service = UserService(db)
        
        # 不能删除自己
        if user_id == current_user["user_id"]:
            return error_response(
                message="不能删除自己",
                code=BusinessCode.OPERATION_FAILED
            )
        
        # 获取用户信息
        user = user_service.get_user_by_id(user_id)
        
        # 删除用户
        success = user_service.delete_user(user_id)
        
        if success:
            logger.info(f"✅ 用户删除成功: {user.username} by {current_user['username']}")
            return success_response(message="用户删除成功")
        else:
            return error_response(
                message="用户删除失败",
                code=BusinessCode.OPERATION_FAILED
            )
        
    except BusinessException as e:
        return error_response(
            message=str(e),
            code=e.code
        )
    except Exception as e:
        logger.error(f"❌ 删除用户异常: {e}")
        return error_response(
            message="删除用户失败",
            code=BusinessCode.DATA_NOT_FOUND if "不存在" in str(e) else BusinessCode.OPERATION_FAILED
        )